<!DOCTYPE html>
<html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>文档智能生成平台</title>
        <script src="https://cdn.tailwindcss.com"></script>
        <link href="https://cdn.jsdelivr.net/npm/inter-ui@3.19.3/inter.min.css" rel="stylesheet">
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
        <script>
            tailwind.config = {
                theme: {
                    extend: {
                        fontFamily: {
                            sans: ['Inter', 'sans-serif'],
                        },
                        colors: {
                            primary: {
                                50: '#eef2ff',
                                100: '#e0e7ff',
                                200: '#c7d2fe',
                                300: '#a5b4fc',
                                400: '#818cf8',
                                500: '#6366f1',
                                600: '#4f46e5',
                                700: '#4338ca',
                                800: '#3730a3',
                                900: '#312e81',
                            }
                        }
                    }
                }
            }
        </script>
    </head>
    <body class="bg-gray-50 font-sans min-h-screen flex flex-col">
        <!-- 加载中遮罩 -->
        <div id="loadingOverlay"
             class="fixed inset-0 bg-white bg-opacity-80 z-50 flex items-center justify-center hidden">
            <div class="text-center">
                <div class="inline-block animate-spin rounded-full h-8 w-8 border-t-2 border-b-2 border-primary-600"></div>
                <p class="mt-2 text-primary-800 font-medium" id="loadingText">正在处理，请稍候...</p>
            </div>
        </div>

        <!-- 顶部导航 -->
        <nav class="bg-white shadow-sm">
            <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
                <div class="flex justify-between h-16">
                    <div class="flex items-center">
                        <div class="flex-shrink-0 flex items-center">
                            <svg class="h-8 w-8 text-primary-600" xmlns="http://www.w3.org/2000/svg" fill="none"
                                 viewBox="0 0 24 24" stroke="currentColor">
                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                                      d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
                            </svg>
                            <span class="ml-2 text-xl font-semibold text-gray-900">文档智能生成平台</span>
                        </div>
                    </div>
                    <div class="flex items-center">
                        <a href="/docs"
                           class="ml-4 px-3 py-2 rounded-md text-sm font-medium text-gray-700 hover:text-gray-900 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-primary-500">
                            <i class="fas fa-home mr-1"></i> 首页
                        </a>
                        <a href="/tasks/list"
                           class="ml-4 px-3 py-2 rounded-md text-sm font-medium text-primary-700 hover:text-primary-800 hover:bg-primary-100 focus:outline-none focus:ring-2 focus:ring-primary-500">
                            <i class="fas fa-tasks mr-1"></i> 任务管理
                        </a>
                    </div>
                </div>
            </div>
        </nav>

        <!-- 主容器 -->
        <main class="flex-grow max-w-7xl w-full mx-auto px-4 sm:px-6 lg:px-8 py-10">
            <div class="mb-10">
                <div class="text-center">
                    <h1 class="text-3xl font-extrabold text-gray-900 sm:text-4xl">
                        智能需求文档生成
                    </h1>
                    <p class="mt-3 max-w-2xl mx-auto text-xl text-gray-500 sm:mt-4">
                        从Excel表格一键生成专业规范的需求文档，提升团队协作效率
                    </p>
                </div>

                <div class="mt-10 flex justify-center">
                    <div class="relative w-full max-w-5xl overflow-hidden rounded-xl shadow-lg">
                        <img src="https://images.unsplash.com/photo-1522071820081-009f0129c71c?ixlib=rb-4.0.3&auto=format&fit=crop&w=1200&q=80"
                             alt="团队协作" class="w-full h-64 object-cover">
                        <div class="absolute inset-0 bg-gradient-to-r from-primary-600/80 to-primary-800/80 mix-blend-multiply"></div>
                        <div class="absolute inset-0 flex items-center justify-center">
                            <div class="text-center text-white px-6">
                                <h2 class="text-2xl font-bold tracking-tight sm:text-3xl">简化您的需求管理流程</h2>
                                <p class="mt-2 text-lg">轻松上传Excel，快速导出专业文档</p>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <!-- 步骤导航 -->
            <div class="mb-8 px-4 sm:px-6 lg:px-8 w-full">
                <div class="flex items-center justify-center">
                    <ol class="flex items-center w-full max-w-4xl mx-auto relative">
                        <!-- 步骤1 -->
                        <li class="flex items-center relative flex-1 text-primary-600">
                            <!-- 步骤1连接线 -->
                            <div class="absolute left-1/2 h-0.5 top-1/2 transform -translate-y-1/2 bg-primary-300 w-full z-0" style="left: 50%"></div>
                            <!-- 步骤1圆圈 -->
                            <div class="relative flex items-center justify-center w-12 h-12 bg-primary-100 rounded-full shrink-0 border-4 border-primary-500 z-10 mx-auto">
                                <span class="flex items-center justify-center bg-primary-500 text-white rounded-full h-8 w-8 text-lg font-semibold">
                                1
                            </span>
                            </div>
                            <!-- 步骤1文字 -->
                            <div class="absolute w-full text-center -bottom-8">
                                <span class="text-sm font-medium text-primary-600">上传Excel</span>
                            </div>
                        </li>
                        
                        <!-- 步骤2 -->
                        <li class="flex items-center relative flex-1">
                            <!-- 步骤2连接线 -->
                            <div class="absolute right-1/2 h-0.5 top-1/2 transform -translate-y-1/2 bg-gray-200 w-full z-0"></div>
                            <div class="absolute left-1/2 h-0.5 top-1/2 transform -translate-y-1/2 bg-gray-200 w-full z-0"></div>
                            <!-- 步骤2圆圈 -->
                            <div class="relative flex items-center justify-center w-12 h-12 bg-gray-100 rounded-full shrink-0 border-4 border-gray-200 z-10 mx-auto">
                                <span class="flex items-center justify-center bg-gray-500 text-white rounded-full h-8 w-8 text-lg font-semibold">
                                2
                            </span>
                            </div>
                            <!-- 步骤2文字 -->
                            <div class="absolute w-full text-center -bottom-8">
                                <span class="text-sm font-medium text-gray-500">选择需求</span>
                            </div>
                        </li>
                        
                        <!-- 步骤3 -->
                        <li class="flex items-center relative flex-1">
                            <!-- 步骤3连接线 -->
                            <div class="absolute right-1/2 h-0.5 top-1/2 transform -translate-y-1/2 bg-gray-200 w-full z-0"></div>
                            <!-- 步骤3圆圈 -->
                            <div class="relative flex items-center justify-center w-12 h-12 bg-gray-100 rounded-full shrink-0 border-4 border-gray-200 z-10 mx-auto">
                                <span class="flex items-center justify-center bg-gray-500 text-white rounded-full h-8 w-8 text-lg font-semibold">
                                3
                            </span>
                            </div>
                            <!-- 步骤3文字 -->
                            <div class="absolute w-full text-center -bottom-8">
                                <span class="text-sm font-medium text-gray-500">生成完成</span>
                            </div>
                        </li>
                    </ol>
                </div>
            </div>

            <!-- 步骤内容区域 -->
            <div class="mt-8">
                <!-- 步骤1: 上传Excel -->
                <div id="step1" class="bg-white shadow-sm sm:rounded-lg overflow-hidden">
                    <div class="px-4 py-5 sm:p-6">
                        <div class="flex items-center mb-4">
                            <div class="flex-shrink-0 h-10 w-10 rounded-full bg-primary-100 flex items-center justify-center">
                                <i class="fas fa-file-excel text-primary-600"></i>
                            </div>
                            <h3 class="ml-3 text-lg font-medium text-gray-900">上传需求Excel文件</h3>
                        </div>

                        <div class="mt-5">
                            <form id="uploadForm" enctype="multipart/form-data">
                                <div class="mt-1 flex justify-center px-6 pt-5 pb-6 border-2 border-gray-300 border-dashed rounded-md hover:border-primary-400 transition-colors">
                                    <div class="space-y-1 text-center">
                                        <svg class="mx-auto h-12 w-12 text-gray-400" stroke="currentColor" fill="none"
                                             viewBox="0 0 48 48">
                                            <path d="M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02"
                                                  stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                        </svg>
                                        <div class="flex text-sm text-gray-600">
                                            <label for="excelFile"
                                                   class="relative cursor-pointer bg-white rounded-md font-medium text-primary-600 hover:text-primary-500 focus-within:outline-none">
                                                <span>选择文件</span>
                                                <input id="excelFile" name="excelFile" type="file" class="sr-only"
                                                       accept=".xlsx, .xls">
                                            </label>
                                            <p class="pl-1">或拖放至此</p>
                                        </div>
                                        <p class="text-xs text-gray-500">支持 .xlsx 和 .xls 格式</p>
                                        
                                        <!-- 文件状态显示区域 -->
                                        <div id="fileStatus" class="hidden mt-2">
                                            <div class="flex items-center justify-center">
                                                <i class="fas fa-file-excel text-primary-500 mr-2"></i>
                                                <span id="selectedFileName" class="text-sm font-medium text-gray-700 mr-2">filename.xlsx</span>
                                                <button id="removeFileBtn" type="button" class="text-gray-400 hover:text-gray-500 focus:outline-none">
                                                    <i class="fas fa-times-circle"></i>
                                                </button>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <div class="mt-4 text-right">
                                    <button type="button" id="uploadBtn"
                                            class="inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
                                        <i class="fas fa-upload mr-2"></i> <span id="uploadBtnText">上传并解析</span>
                                    </button>
                                </div>

                                <!-- 上传进度指示器 -->
                                <div id="uploadProgress" class="mt-2 hidden">
                                    <div class="w-full bg-gray-200 rounded-full h-2.5">
                                        <div id="uploadProgressBar" class="bg-primary-600 h-2.5 rounded-full transition-all duration-300" style="width: 0%"></div>
                                    </div>
                                    <p id="uploadStatus" class="text-xs text-gray-500 mt-1 text-center">准备上传...</p>
                                </div>
                            </form>
                        </div>
                    </div>
                </div>

                <!-- 步骤2: 选择需求 -->
                <div id="step2" class="hidden bg-white shadow-sm sm:rounded-lg overflow-hidden">
                    <div class="px-4 py-5 sm:p-6">
                        <div class="flex items-center mb-4">
                            <div class="flex-shrink-0 h-10 w-10 rounded-full bg-primary-100 flex items-center justify-center">
                                <i class="fas fa-check-square text-primary-600"></i>
                            </div>
                            <h3 class="ml-3 text-lg font-medium text-gray-900">选择需求</h3>
                        </div>

                        <div class="mt-4">
                            <div class="flex justify-between items-center">
                                <h4 class="text-base font-medium text-gray-900">已发现的需求列表</h4>
                                <div class="inline-flex rounded-md shadow-sm">
                                    <button type="button" id="selectAllBtn"
                                            class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-l-md text-primary-700 bg-primary-100 hover:bg-primary-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
                                        <i class="fas fa-check-double mr-2"></i> 全选
                                    </button>
                                    <button type="button" id="deselectAllBtn"
                                            class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-r-md text-gray-700 bg-gray-100 hover:bg-gray-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500">
                                        <i class="fas fa-times mr-2"></i> 取消全选
                                    </button>
                                </div>
                            </div>

                            <div class="mt-4 relative">
                                <div class="absolute inset-0 flex items-center" aria-hidden="true">
                                    <div class="w-full border-t border-gray-300"></div>
                                </div>
                                <div class="relative flex justify-start">
                                <span class="pr-3 bg-white text-sm text-gray-500">
                                    <i class="fas fa-filter mr-1"></i> 需求筛选
                                </span>
                                </div>
                            </div>

                            <div class="mt-3 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
                                <div class="flex">
                                    <div class="relative flex-1">
                                        <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
                                            <i class="fas fa-search text-gray-400"></i>
                                        </div>
                                        <input type="text" id="searchInput"
                                               class="focus:ring-primary-500 focus:border-primary-500 block w-full pl-10 pr-12 sm:text-sm border-gray-300 rounded-md"
                                               placeholder="搜索需求">
                                    </div>
                                </div>

                                <div class="flex items-center">
                                    <label for="sortBy" class="sr-only">排序方式</label>
                                    <select id="sortBy"
                                            class="focus:ring-primary-500 focus:border-primary-500 h-full py-0 pl-2 pr-7 border-transparent bg-transparent text-gray-500 sm:text-sm rounded-md">
                                        <option value="reqNo">按需求编号排序</option>
                                        <option value="reqName">按需求名称排序</option>
                                        <option value="expectOnlineTime">按预计上线时间排序</option>
                                    </select>
                                </div>
                            </div>
                        </div>

                        <!-- 需求列表 -->
                        <div class="mt-6">
                            <div id="reqList" class="mt-1 grid grid-cols-1 gap-4">
                                <!-- 需求列表将在这里动态生成 -->
                            </div>

                            <div id="emptyState"
                                 class="hidden my-12 flex flex-col items-center justify-center text-center">
                                <svg class="mx-auto h-12 w-12 text-gray-400" fill="none" viewBox="0 0 24 24"
                                     stroke="currentColor" aria-hidden="true">
                                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                                          d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
                                </svg>
                                <h3 class="mt-2 text-sm font-medium text-gray-900">没有找到需求</h3>
                                <p class="mt-1 text-sm text-gray-500">请检查上传的Excel文件是否包含有效的需求数据。</p>
                            </div>
                        </div>

                        <div class="mt-10 flex justify-between">
                            <button type="button" id="backToStep1Btn"
                                    class="inline-flex items-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
                                <i class="fas fa-arrow-left mr-2"></i> 返回上传
                            </button>

                            <button type="button" id="generateBtn"
                                    class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
                                <i class="fas fa-file-word mr-2"></i> 生成文档
                            </button>
                        </div>
                    </div>
                </div>

                <!-- 步骤3: 完成 -->
                <div id="step3" class="hidden space-y-8">
                    <!-- 结果头部 -->
                    <div class="mt-6 bg-green-50 border-l-4 border-green-400 p-4">
                            <div class="flex">
                                <div class="flex-shrink-0">
                                <svg class="h-5 w-5 text-green-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
                                    <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />
                                </svg>
                                </div>
                                <div class="ml-3">
                                <h3 class="text-sm font-medium text-green-800">任务已提交成功</h3>
                                    <div class="mt-2 text-sm text-green-700">
                                    <p>文档生成任务已提交，系统将在后台处理，处理完成后您可以下载文档。</p>
                                    </div>
                                </div>
                            </div>
                        </div>

                    <!-- 任务信息 -->
                    <div id="taskInfo" class="hidden mt-4 border border-gray-200 rounded-md overflow-hidden">
                        <div class="bg-gray-50 px-4 py-5 sm:px-6">
                            <div class="flex items-center justify-between">
                                <h3 class="text-lg leading-6 font-medium text-gray-900">任务信息</h3>
                                <span id="taskStatus"></span>
                            </div>
                            <div class="mt-2 max-w-2xl text-sm text-gray-500">
                                <p>任务ID: <span id="taskIdDisplay" class="font-mono"></span>
                                <a id="taskIdLink" href="#" class="ml-2 text-primary-600 hover:text-primary-500">
                                    <i class="fas fa-external-link-alt"></i> 查看详情
                                </a>
                                </p>
                        </div>

                            <!-- 任务进度条 -->
                            <div id="taskProgress" class="hidden mt-3">
                                <div class="w-full bg-gray-200 rounded-full h-2.5">
                                    <div id="taskProgressBar" class="bg-blue-500 h-2.5 rounded-full" style="width: 10%"></div>
                                </div>
                                <div class="mt-1 text-xs text-gray-500 text-right"><span id="taskProgressText">10%</span></div>
                                </div>
                            </div>
                        </div>

                    <!-- 按钮组 -->
                        <div class="mt-10 flex justify-between">
                            <button type="button" id="backToStep1FromFinishBtn"
                                    class="inline-flex items-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
                                <i class="fas fa-arrow-left mr-2"></i> 返回上传
                            </button>

                        <div class="flex space-x-3">
                            <button type="button" id="downloadZipBtn"
                                    class="inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 opacity-50 cursor-not-allowed" disabled>
                                <i class="fas fa-download mr-2"></i> 下载压缩包
                            </button>
                            
                            <a href="/tasks/list" class="inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-gray-600 hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500">
                                <i class="fas fa-list mr-2"></i> 查看所有任务
                            </a>
                        </div>
                    </div>
                </div>
            </div>
        </main>

        <!-- 页脚 -->
        <footer class="bg-white border-t border-gray-200 mt-auto">
            <div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
                <p class="text-center text-sm text-gray-500">© 2025 文档智能生成平台 | 版本 2.0</p>
            </div>
        </footer>

        <div th:replace="fragments/progress-modal :: progressModal"></div>
        <script th:replace="fragments/progress-modal :: progressScripts"></script>

        <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
        <script>
            // 页面加载完成后执行
            document.addEventListener('DOMContentLoaded', function () {
                    // 获取步骤元素
                    const step1 = document.getElementById('step1');
                    const step2 = document.getElementById('step2');
                    const step3 = document.getElementById('step3');
                                        // 获取按钮元素                    const uploadBtn = document.getElementById('uploadBtn');                    const backToStep1Btn = document.getElementById('backToStep1Btn');                    const backToStep1FromFinishBtn = document.getElementById('backToStep1FromFinishBtn');                    const generateBtn = document.getElementById('generateBtn');                    const selectAllBtn = document.getElementById('selectAllBtn');                    const deselectAllBtn = document.getElementById('deselectAllBtn');                    const downloadZipBtn = document.getElementById('downloadZipBtn');                    const copyPathBtn = document.getElementById('copyPathBtn');
                    const searchInput = document.getElementById('searchInput');
                    const sortBySelect = document.getElementById('sortBy');
                    // 文件选择器增强
                    const fileInput = document.getElementById('excelFile');
                    const fileInputContainer = fileInput.closest('.flex');
                    const fileStatus = document.getElementById('fileStatus');
                    const selectedFileName = document.getElementById('selectedFileName');
                    const removeFileBtn = document.getElementById('removeFileBtn');
                    const uploadStatus = document.getElementById('uploadStatus');
                    const uploadProgress = document.getElementById('uploadProgress');
                    const uploadProgressBar = document.getElementById('uploadProgressBar');
                    const uploadBtnText = document.getElementById('uploadBtnText');
                    
                    // 存储数据
                    let filePath = '';
                    let fileHash = '';
                    let reqItems = [];
                    let startTime = 0;
                    // 步骤导航元素
                    const stepIndicators = document.querySelectorAll('ol.flex.items-center li');
                    
                    // ===== 功能函数定义 =====

                    // 显示加载中
                    function showLoading(text) {
                        document.getElementById('loadingText').innerText = text || '正在处理，请稍候...';
                        document.getElementById('loadingOverlay').classList.remove('hidden');
                    }

                    // 隐藏加载中
                    function hideLoading() {
                        document.getElementById('loadingOverlay').classList.add('hidden');
                    }

                    // 显示通知
                    function showNotification(message, type = 'success') {
                        // 创建通知元素
                        const notification = document.createElement('div');
                        let bgColor, textColor, iconClass;
                        if (type === 'success') {
                            bgColor = 'bg-green-50';
                            textColor = 'text-green-800';
                            iconClass = 'fa-check-circle text-green-400';
                        } else if (type === 'error') {
                            bgColor = 'bg-red-50';
                            textColor = 'text-red-800';
                            iconClass = 'fa-exclamation-circle text-red-400';
                        } else if (type === 'warning') {
                            bgColor = 'bg-yellow-50';
                            textColor = 'text-yellow-800';
                            iconClass = 'fa-exclamation-triangle text-yellow-400';
                        } else {
                            bgColor = 'bg-blue-50';
                            textColor = 'text-blue-800';
                            iconClass = 'fa-info-circle text-blue-400';
                        }
                        notification.className = `fixed top-4 right-4 w-80 ${bgColor} border-l-4 border-${type === 'success' ? 'green' : type === 'error' ? 'red' : type === 'warning' ? 'yellow' : 'blue'}-400 p-4 shadow-md rounded transform transition-all duration-300 ease-in-out z-50`;
                        notification.innerHTML = `                    <div class="flex">                        <div class="flex-shrink-0">                            <i class="fas ${iconClass}"></i>                        </div>                        <div class="ml-3">                            <p class="text-sm font-medium ${textColor}">${message}</p>                        </div>                        <div class="ml-auto pl-3">                            <div class="-mx-1.5 -my-1.5">                                <button type="button" class="inline-flex ${bgColor} rounded-md p-1.5 ${textColor} hover:bg-${type === 'success' ? 'green' : type === 'error' ? 'red' : type === 'warning' ? 'yellow' : 'blue'}-100 focus:outline-none">                                    <span class="sr-only">关闭</span>                                    <i class="fas fa-times"></i>                                </button>                            </div>                        </div>                    </div>                `;
                        // 添加到页面
                        document.body.appendChild(notification);
                        // 点击关闭按钮
                        notification.querySelector('button').addEventListener('click', () => {
                            notification.classList.add('opacity-0');
                            setTimeout(() => {
                                document.body.removeChild(notification);
                            }, 300);
                        });
                        // 自动关闭
                        setTimeout(() => {
                            notification.classList.add('opacity-0');
                            setTimeout(() => {
                                if (document.body.contains(notification)) {
                                    document.body.removeChild(notification);
                                }
                            }, 300);
                        }, 5000);
                    }
                    
                    // 重置文件选择状态
                    function resetFileSelection() {
                        fileInput.value = '';
                        fileStatus.classList.add('hidden');
                        uploadProgress.classList.add('hidden');
                        uploadBtnText.textContent = '上传并解析';
                    }
                    
                    // 显示上传进度
                    function showUploadProgress(percent, statusText) {
                        if (uploadProgress.classList.contains('hidden')) {
                            uploadProgress.classList.remove('hidden');
                        }
                        uploadProgressBar.style.width = `${percent}%`;
                        uploadStatus.textContent = statusText || `上传中 (${percent}%)`;
                        
                        if (percent === 100) {
                            uploadStatus.textContent = '解析中...';
                        }
                    }

                    // 显示步骤
                    function showStep(stepNumber) {
                        console.log("显示步骤：", stepNumber);
                        // 隐藏所有步骤
                        step1.classList.add('hidden');
                        step2.classList.add('hidden');
                        step3.classList.add('hidden');

                        // 特别处理第二步到第三步的连接线
                        if (stepNumber === 3) {
                            // 找到第二步和第三步之间的连接线
                            const step2El = stepIndicators[1]; // 第二步元素(索引从0开始)
                            const rightLineStep2 = step2El.querySelector('.absolute.right-1\\/2');
                            if (rightLineStep2) {
                                rightLineStep2.classList.remove('bg-gray-200');
                                rightLineStep2.classList.add('bg-primary-300');
                            }
                            
                            const step3El = stepIndicators[2]; // 第三步元素
                            const leftLineStep3 = step3El.querySelector('.absolute.left-1\\/2');
                            if (leftLineStep3) {
                                leftLineStep3.classList.remove('bg-gray-200');
                                leftLineStep3.classList.add('bg-primary-300');
                            }
                        }

                        // 更新步骤指示器
                        stepIndicators.forEach((indicator, index) => {
                            const stepNum = index + 1;
                            
                            // 选择步骤圆圈 - 兼容新旧DOM结构
                            let circle, span, stepText, leftLine, rightLine;
                            try {
                                // 新DOM结构
                                circle = indicator.querySelector('div.relative'); 
                                span = circle.querySelector('span');
                                stepText = indicator.querySelector('.absolute.w-full span');
                                leftLine = indicator.querySelector('.absolute.left-1\\/2');
                                rightLine = indicator.querySelector('.absolute.right-1\\/2');
                            } catch (e) {
                                // 旧DOM结构备用方案
                                console.log("使用旧DOM结构选择器", e);
                                circle = indicator.querySelector('div');
                                span = indicator.querySelector('span');
                            }

                            if (stepNum < stepNumber) {
                                // 已完成的步骤
                                // 更新圆圈样式
                                if (circle) {
                                circle.classList.remove('border-gray-200', 'bg-gray-100');
                                circle.classList.add('border-primary-500', 'bg-primary-100');
                                }
                                
                                // 更新数字样式
                                if (span) {
                                span.classList.remove('bg-gray-500');
                                span.classList.add('bg-primary-500');
                                }
                                
                                // 更新文字样式
                                if (stepText) {
                                    stepText.classList.remove('text-gray-500');
                                    stepText.classList.add('text-primary-600');
                                }
                                
                                // 更新右侧连接线
                                if (rightLine) {
                                    rightLine.classList.remove('bg-gray-200');
                                    rightLine.classList.add('bg-primary-300');
                                }
                                
                                // 当前步骤的左侧连接线也应该是完成状态
                                if (stepNum + 1 === stepNumber && stepIndicators[stepNum]) {
                                    try {
                                        const nextLeftLine = stepIndicators[stepNum].querySelector('.absolute.left-1\\/2');
                                        if (nextLeftLine) {
                                            nextLeftLine.classList.remove('bg-gray-200');
                                            nextLeftLine.classList.add('bg-primary-300');
                                        }
                                    } catch (e) {
                                        console.log("更新连接线失败", e);
                                    }
                                }
                                
                                // 兼容旧DOM结构
                                if (indicator.classList.contains('after:border-gray-200')) {
                                    indicator.classList.remove('after:border-gray-200');
                                    indicator.classList.add('after:border-primary-300');
                                }
                            } else if (stepNum === stepNumber) {
                                // 当前步骤
                                // 更新圆圈样式
                                if (circle) {
                                circle.classList.remove('border-gray-200', 'bg-gray-100');
                                circle.classList.add('border-primary-500', 'bg-primary-100');
                                }
                                
                                // 更新数字样式
                                if (span) {
                                span.classList.remove('bg-gray-500');
                                span.classList.add('bg-primary-500');
                                }
                                
                                // 更新文字样式
                                if (stepText) {
                                    stepText.classList.remove('text-gray-500');
                                    stepText.classList.add('text-primary-600');
                                }

                                // 右侧连接线保持灰色，除非是最后一步
                                if (rightLine && stepNum < 3) {
                                    rightLine.classList.remove('bg-primary-300');
                                    rightLine.classList.add('bg-gray-200');
                                }
                                
                                // 兼容旧DOM结构
                                if (indicator.classList.contains('after:border-primary-300')) {
                                    indicator.classList.remove('after:border-primary-300');
                                    indicator.classList.add('after:border-gray-200');
                                }
                            } else {
                                // 未完成的步骤
                                // 更新圆圈样式
                                if (circle) {
                                circle.classList.remove('border-primary-500', 'bg-primary-100');
                                circle.classList.add('border-gray-200', 'bg-gray-100');
                                }
                                
                                // 更新数字样式
                                if (span) {
                                span.classList.remove('bg-primary-500');
                                span.classList.add('bg-gray-500');
                                }
                                
                                // 更新文字样式
                                if (stepText) {
                                    stepText.classList.remove('text-primary-600');
                                    stepText.classList.add('text-gray-500');
                                }
                                
                                // 连接线保持灰色
                                if (leftLine) {
                                    leftLine.classList.remove('bg-primary-300');
                                    leftLine.classList.add('bg-gray-200');
                                }
                                
                                if (rightLine) {
                                    rightLine.classList.remove('bg-primary-300');
                                    rightLine.classList.add('bg-gray-200');
                                }
                                
                                // 兼容旧DOM结构
                                if (indicator.classList.contains('after:border-primary-300')) {
                                    indicator.classList.remove('after:border-primary-300');
                                    indicator.classList.add('after:border-gray-200');
                                }
                            }
                        });

                        console.log("显示步骤内容：", stepNumber);
                        // 显示对应步骤
                        if (stepNumber === 1) {
                            step1.classList.remove('hidden');
                        } else if (stepNumber === 2) {
                            step2.classList.remove('hidden');
                        } else if (stepNumber === 3) {
                            step3.classList.remove('hidden');
                        }
                    }

                    // 复制文本到剪贴板
                    function copyToClipboard(text) {
                        const textarea = document.createElement('textarea');
                        textarea.value = text;
                        document.body.appendChild(textarea);
                        textarea.select();
                        document.execCommand('copy');
                        document.body.removeChild(textarea);

                        // 显示复制成功提示
                        const originalHTML = copyPathBtn.innerHTML;
                        copyPathBtn.innerHTML = '<i class="fas fa-check"></i>';
                        copyPathBtn.classList.add('text-green-500');

                        setTimeout(() => {
                            copyPathBtn.innerHTML = originalHTML;
                            copyPathBtn.classList.remove('text-green-500');
                        }, 2000);
                    }

                    function updateReqCardSelection(card, isSelected) {
                        if (isSelected) {
                            card.classList.add('ring-2', 'ring-primary-500');
                            card.classList.remove('hover:shadow-md');
                            card.classList.add('shadow-md');
                        } else {
                            card.classList.remove('ring-2', 'ring-primary-500');
                            card.classList.add('hover:shadow-md');
                            card.classList.remove('shadow-md');
                        }
                    }
                    
                    // 渲染需求列表
                    function renderReqList(filteredItems) {
                        const reqListElement = document.getElementById('reqList');
                        const emptyState = document.getElementById('emptyState');
                        
                        console.log("开始渲染需求列表:", filteredItems ? filteredItems.length : 0, "个项目");
                        
                        if (!reqListElement) {
                            console.error("找不到reqList元素");
                            return;
                        }
                        
                        if (!emptyState) {
                            console.warn("找不到emptyState元素");
                        }
                        
                        // 清空现有内容
                        reqListElement.innerHTML = '';
                        
                        if (!filteredItems || filteredItems.length === 0) {
                            // 显示空状态
                            if (emptyState) {
                                emptyState.classList.remove('hidden');
                            }
                            console.log("需求列表为空，显示空状态");
                            return;
                        }
                        
                        // 隐藏空状态
                        if (emptyState) {
                            emptyState.classList.add('hidden');
                        }
                        
                        console.log("开始渲染", filteredItems.length, "个需求项");
                        
                        try {
                            // 遍历并渲染每个需求项
                            filteredItems.forEach((item, index) => {
                                if (!item) {
                                    console.warn("跳过无效项目:", index);
                                    return;
                                }
                                
                                const reqNo = item.reqNo || `item-${index}`;
                                const reqName = item.reqName || '未命名需求';
                                
                                try {
                                    const card = document.createElement('div');
                                    card.className = 'relative bg-white border rounded-lg overflow-hidden transition-all duration-200 hover:shadow-md';
                                    
                                    // 格式化日期
                                    const formatDate = (dateString) => {
                                        if (!dateString) return '未设置';
                                        try {
                                            const date = new Date(dateString);
                                            return date.toLocaleDateString('zh-CN');
                                        } catch (e) {
                                            console.warn("日期格式化失败:", e);
                                            return dateString;
                                        }
                                    };
                                    
                                    card.innerHTML = `
                                        <div class="absolute top-3 right-3">
                                            <input type="checkbox" class="req-checkbox form-checkbox h-5 w-5 text-primary-600 rounded border-gray-300 focus:ring-primary-500" value="${reqNo}">
                                        </div>
                                        <div class="p-4">
                                            <div class="flex justify-between">
                                                <div class="font-medium text-gray-900">${reqName}</div>
                                            </div>
                                            <div class="mt-2">
                                                <div class="flex items-center text-sm text-gray-500">
                                                    <span class="mr-2 flex-shrink-0 font-medium">需求编号:</span>
                                                    <span>${reqNo}</span>
                                                </div>
                                                <div class="mt-1 flex items-center text-sm text-gray-500">
                                                    <span class="mr-2 flex-shrink-0 font-medium">需求负责人:</span>
                                                    <span>${item.reqOwner || '-'}</span>
                                                </div>
                                                <div class="mt-1 flex items-center text-sm text-gray-500">
                                                    <span class="mr-2 flex-shrink-0 font-medium">开发负责人:</span>
                                                    <span>${item.reqDeveloper || '-'}</span>
                                                </div>
                                                 <div class="mt-1 flex items-center text-sm text-gray-500">
                                                    <span class="mr-2 flex-shrink-0 font-medium">拆分表:</span>
                                                    <span>${item.itemSize || '-'}条</span>
                                                </div>
                                                <div class="mt-1 flex items-center text-sm text-gray-500">
                                                    <span class="mr-2 flex-shrink-0 font-medium">预计上线时间:</span>
                                                    <span>${formatDate(item.expectOnlineTime)}</span>
                                                </div>
                                            </div>
                                            <div class="mt-3">
                                                <div class="text-sm text-gray-700 line-clamp-2">${item.reqDesc || '无描述'}</div>
                                            </div>
                                        </div>
                                    `;
                                    
                                    // 添加到列表
                                    reqListElement.appendChild(card);
                                    
                                    // 处理复选框点击事件
                                    const checkbox = card.querySelector('.req-checkbox');
                                    if (checkbox) {
                                        checkbox.addEventListener('change', function() {
                                            updateReqCardSelection(card, this.checked);
                                        });
                                        
                                        // 点击卡片也可以选择/取消选择
                                        card.addEventListener('click', function(e) {
                                            // 排除点击复选框的情况
                                            if (e.target !== checkbox) {
                                                checkbox.checked = !checkbox.checked;
                                                updateReqCardSelection(card, checkbox.checked);
                                            }
                                        });
                                    }
                                } catch (cardError) {
                                    console.error("创建卡片失败:", cardError, "项目:", item);
                                }
                            });
                            
                            console.log("需求列表渲染完成");
                        } catch (e) {
                            console.error("渲染需求列表失败:", e);
                            // 提供后备方案，简单渲染
                            reqListElement.innerHTML = '<div class="p-4 bg-red-50 text-red-700 rounded"><p>渲染需求列表出错，请刷新页面重试</p></div>';
                        }
                    }

                    // 搜索和筛选需求
                    function filterRequirements() {
                        const searchTerm = searchInput.value.toLowerCase();
                        const sortBy = sortBySelect.value;

                        // 克隆原始数据进行排序
                        let filteredItems = [...reqItems];

                        // 应用搜索过滤
                        if (searchTerm) {
                            filteredItems = filteredItems.filter(item =>
                                (item.reqName && item.reqName.toLowerCase().includes(searchTerm)) ||
                                (item.reqNo && item.reqNo.toString().toLowerCase().includes(searchTerm)) ||
                                (item.reqDesc && item.reqDesc.toLowerCase().includes(searchTerm)) ||
                                (item.reqOwner && item.reqOwner.toLowerCase().includes(searchTerm)) ||
                                (item.reqDeveloper && item.reqDeveloper.toLowerCase().includes(searchTerm))
                            );
                        }

                        // 应用排序
                        if (sortBy === 'reqNo') {
                            filteredItems.sort((a, b) => a.reqNo.localeCompare(b.reqNo));
                        } else if (sortBy === 'reqName') {
                            filteredItems.sort((a, b) => (a.reqName || '').localeCompare(b.reqName || ''));
                        } else if (sortBy === 'expectOnlineTime') {
                            filteredItems.sort((a, b) => {
                                const dateA = a.expectOnlineTime ? new Date(a.expectOnlineTime) : new Date(0);
                                const dateB = b.expectOnlineTime ? new Date(b.expectOnlineTime) : new Date(0);
                                return dateA - dateB;
                            });
                        }

                        // 重新渲染列表
                        renderReqList(filteredItems);
                    }
                    
                    function preventDefaults(e) {
                        e.preventDefault();
                        e.stopPropagation();
                    }
                    
                    function highlight() {
                        dropZone.classList.add('border-primary-400', 'bg-primary-50');
                        // 添加指示器
                        const dropIndicator = document.createElement('div');
                        dropIndicator.id = 'drop-indicator';
                        dropIndicator.className = 'absolute inset-0 flex items-center justify-center bg-primary-100 bg-opacity-70 z-10 rounded-md';
                        dropIndicator.innerHTML = `
                            <div class="text-center">
                                <i class="fas fa-file-import text-primary-500 text-3xl mb-2"></i>
                                <p class="text-primary-700 font-medium">放开以上传文件</p>
                            </div>
                        `;
                        
                        // 只添加一次
                        if (!document.getElementById('drop-indicator')) {
                            dropZone.style.position = 'relative';
                            dropZone.appendChild(dropIndicator);
                        }
                    }

                    function unhighlight() {
                        dropZone.classList.remove('border-primary-400', 'bg-primary-50');
                        // 移除指示器
                        const dropIndicator = document.getElementById('drop-indicator');
                        if (dropIndicator) {
                            dropZone.removeChild(dropIndicator);
                        }
                    }
                    
                    function handleDrop(e) {
                        const dt = e.dataTransfer;
                        const files = dt.files;
                        
                        if (files.length > 0) {
                            // 检查是否为Excel文件
                            const file = files[0];
                            const fileExt = file.name.split('.').pop().toLowerCase();
                            
                            if (['xlsx', 'xls'].includes(fileExt)) {
                                // 设置文件到input
                                fileInput.files = files;
                                
                                // 触发change事件
                                const event = new Event('change');
                                fileInput.dispatchEvent(event);
                                
                                // 显示动画提示可以上传
                                uploadBtn.classList.add('animate-pulse');
                                setTimeout(() => {
                                    uploadBtn.classList.remove('animate-pulse');
                                }, 1500);
                            } else {
                                showNotification('请上传Excel格式的文件（.xlsx或.xls）', 'warning');
                            }
                        }
                    }
                    
                    // ===== 事件处理程序设置 =====
                    
                    // 文件选择事件
                    fileInput.addEventListener('change', function () {
                        if (this.files.length > 0) {
                            const file = this.files[0];
                            // 显示选中的文件名
                            selectedFileName.textContent = file.name;
                            fileStatus.classList.remove('hidden');
                            
                            // 显示通知
                            showNotification(`已选择文件: ${file.name}`, 'info');
                            
                            // 可以直接上传
                            uploadBtn.classList.add('animate-pulse');
                            setTimeout(() => {
                                uploadBtn.classList.remove('animate-pulse');
                            }, 1500);
                        } else {
                            // 清除文件选择状态
                            resetFileSelection();
                        }
                    });
                    
                    // 清除文件选择
                    removeFileBtn.addEventListener('click', function(e) {
                        e.stopPropagation();
                        resetFileSelection();
                    });

                    // 上传Excel按钮点击事件
                    uploadBtn.addEventListener('click', function () {
                        const fileInput = document.getElementById('excelFile');
                        if (!fileInput.files[0]) {
                            showNotification('请选择Excel文件', 'warning');
                            return;
                        }

                        const formData = new FormData();
                        formData.append('excelFile', fileInput.files[0]);

                        showLoading('正在上传和解析Excel文件，请稍候...');
                        startTime = Date.now();
                        
                        // 更新上传按钮状态
                        uploadBtnText.textContent = '上传中...';
                        uploadBtn.disabled = true;
                        uploadBtn.classList.add('opacity-75', 'cursor-not-allowed');
                        
                        // 显示上传进度（模拟，因为实际进度需要后端支持）
                        showUploadProgress(10, '准备上传...');
                        
                        // 模拟上传进度
                        let progressInterval = setInterval(() => {
                            const currentWidth = parseInt(uploadProgressBar.style.width, 10);
                            if (currentWidth < 90) {
                                showUploadProgress(currentWidth + 10, '上传中...');
                            } else {
                                clearInterval(progressInterval);
                            }
                        }, 300);

                        axios.post('/docs/upload', formData)
                            .then(response => {
                                // 完成进度
                                clearInterval(progressInterval);
                                showUploadProgress(100, '上传完成，解析中...');
                                
                                setTimeout(() => {
                                hideLoading();
                                    
                                    // 恢复上传按钮状态
                                    uploadBtn.disabled = false;
                                    uploadBtn.classList.remove('opacity-75', 'cursor-not-allowed');
                                    uploadBtnText.textContent = '上传并解析';
                                    
                                if (response.data.success) {
                                    filePath = response.data.data.filePath || '';
                                    fileHash = response.data.data.fileHash || '';
                                    reqItems = response.data.data.reqInfoList || [];
                                        
                                        // 显示成功通知
                                        try {
                                            showNotification(`成功解析到 ${reqItems.length} 个需求项`, 'success');
                                        } catch (e) {
                                            console.error("显示通知失败:", e);
                                            alert(`成功解析到 ${reqItems.length} 个需求项`);
                                        }
                                        
                                        console.log("渲染需求列表, 项目数:", reqItems.length);
                                        // 先确保渲染
                                    renderReqList(reqItems);
                                        
                                        // 确保切换到步骤2
                                        console.log("切换到步骤2...");
                                        setTimeout(() => {
                                    showStep(2);
                                            // 确保步骤2显示
                                            if (step2.classList.contains('hidden')) {
                                                console.log("步骤2仍然隐藏，强制显示");
                                                step1.classList.add('hidden');
                                                step2.classList.remove('hidden');
                                                step3.classList.add('hidden');
                                            }
                                        }, 100);
                                } else {
                                        try {
                                            showNotification(response.data.message || '上传失败', 'error');
                                        } catch (e) {
                                            console.error("显示通知失败:", e);
                                    alert(response.data.message || '上传失败');
                                }
                                    }
                                }, 500);
                            })
                            .catch(error => {
                                // 清除进度条计时器
                                clearInterval(progressInterval);
                                
                                hideLoading();
                                // 恢复上传按钮状态
                                uploadBtn.disabled = false;
                                uploadBtn.classList.remove('opacity-75', 'cursor-not-allowed');
                                uploadBtnText.textContent = '上传并解析';
                                
                                console.error('上传出错:', error);
                                showNotification('上传失败: ' + (error.response?.data || error.message), 'error');
                            });
                    });

                    // 全选按钮点击事件
                    selectAllBtn.addEventListener('click', function () {
                        document.querySelectorAll('.req-checkbox').forEach(checkbox => {
                            checkbox.checked = true;
                            updateReqCardSelection(checkbox.closest('.relative'), true);
                        });
                    });

                    // 取消全选按钮点击事件
                    deselectAllBtn.addEventListener('click', function () {
                        document.querySelectorAll('.req-checkbox').forEach(checkbox => {
                            checkbox.checked = false;
                            updateReqCardSelection(checkbox.closest('.relative'), false);
                        });
                    });

                    // 返回按钮点击事件
                    backToStep1Btn.addEventListener('click', function () {
                        showStep(1);
                    });

                    // 从完成页返回按钮点击事件
                    backToStep1FromFinishBtn.addEventListener('click', function () {
                        showStep(1);
                    });

                    // 生成文档按钮点击事件
                    generateBtn.addEventListener('click', function () {
                        // 获取选中的需求
                        const selectedReqs = Array.from(document.querySelectorAll('.req-checkbox:checked')).map(checkbox => checkbox.value);

                        if (selectedReqs.length === 0) {
                            showNotification('请至少选择一个需求', 'warning');
                            return;
                        }

                        // 直接用JS变量 fileHash
                        if (!fileHash) {
                            showNotification('文件哈希值不能为空，请重新上传文件', 'error');
                            return;
                        }

                        // 禁用按钮，显示加载中
                        generateBtn.disabled = true;
                        generateBtn.classList.add('opacity-75', 'cursor-not-allowed');
                        const originalText = generateBtn.innerHTML;
                        generateBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> 提交中...';
                        
                        // 显示全屏加载动画
                        showLoading('正在提交生成任务...');

                        // 发起请求生成文档
                        const formData = new FormData();
                        formData.append('fileHash', fileHash);
                        selectedReqs.forEach(req => formData.append('selectedReqs', req));

                        axios.post('/docs/generate', formData)
                            .then(response => {
                                // 先显示任务提交中的加载效果，保持一段时间
                                setTimeout(() => {
                                    hideLoading();
                                    
                                    // 恢复按钮状态
                                    generateBtn.disabled = false;
                                    generateBtn.classList.remove('opacity-75', 'cursor-not-allowed');
                                    generateBtn.innerHTML = originalText;
                                    
                                    if (response.data.success) {
                                        // 获取任务ID
                                        const taskId = response.data.data.taskId;
                                        
                                        // 切换到完成步骤
                                        showStep(3);
                                        
                                        // 添加任务详情链接
                                        document.getElementById('taskIdDisplay').textContent = taskId;
                                        document.getElementById('taskIdLink').href = `/tasks/detail/${taskId}`;
                                        document.getElementById('taskInfo').classList.remove('hidden');
                                        
                                        // 开始轮询任务状态
                                        startTaskPolling(taskId);
                                        
                                        // 显示成功弹窗动画效果（延迟500ms显示）
                                        setTimeout(() => {
                                            const successOverlay = document.createElement('div');
                                            successOverlay.className = 'fixed inset-0 flex items-center justify-center z-50 bg-black bg-opacity-30 transition-opacity duration-300 opacity-0';
                                            successOverlay.innerHTML = `
                                                <div class="bg-white rounded-lg p-8 shadow-xl transform transition-all duration-300 scale-90 max-w-md w-full">
                                                    <div class="text-center">
                                                        <div class="mx-auto flex items-center justify-center h-16 w-16 rounded-full bg-green-100">
                                                            <i class="fas fa-check text-3xl text-green-600"></i>
                                                        </div>
                                                        <h3 class="mt-5 text-xl leading-6 font-medium text-gray-900">任务已成功提交</h3>
                                                        <div class="mt-3">
                                                            <p class="text-sm text-gray-600">系统正在后台处理您的文档生成请求，请耐心等待。</p>
                                                            <p class="mt-2 text-sm font-mono text-gray-800">任务ID: ${taskId}</p>
                                                        </div>
                                                    </div>
                                                </div>
                                            `;
                                            document.body.appendChild(successOverlay);
                                            
                                            // 渲染后添加过渡效果
                                            setTimeout(() => {
                                                successOverlay.classList.add('opacity-100');
                                                successOverlay.querySelector('div').classList.remove('scale-90');
                                                successOverlay.querySelector('div').classList.add('scale-100');
                                            }, 10);
                                            
                                            // 3秒后关闭成功提示
                                            setTimeout(() => {
                                                successOverlay.classList.remove('opacity-100');
                                                successOverlay.classList.add('opacity-0');
                                                successOverlay.querySelector('div').classList.remove('scale-100');
                                                successOverlay.querySelector('div').classList.add('scale-90');
                                                
                                                setTimeout(() => {
                                                    document.body.removeChild(successOverlay);
                                                }, 300);
                                            }, 3000);
                                        }, 500);
                                    } else {
                                        showNotification(response.data.message || '生成文档失败', 'error');
                                    }
                                }, 800); // 保持加载动画至少800ms
                            })
                            .catch(error => {
                                hideLoading();
                                
                                // 恢复按钮状态
                                generateBtn.disabled = false;
                                generateBtn.classList.remove('opacity-75', 'cursor-not-allowed');
                                generateBtn.innerHTML = originalText;
                                
                                showNotification('生成文档失败: ' + (error.response?.data?.message || error.message), 'error');
                            });
                    });

                    // 下载文档压缩包
                    downloadZipBtn.addEventListener('click', function() {
                        // 优先从按钮的data-path属性获取路径
                        const path = this.getAttribute('data-path');
                        // 如果没有，才尝试从输出路径元素获取
                        const outputPathEl = document.getElementById('outputPath');
                        const outputPath = outputPathEl ? outputPathEl.textContent : null;
                        
                        const finalPath = path || outputPath;
                        
                        if (finalPath) {
                            // 显示下载中提示
                            this.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> 打包下载中...';
                            this.disabled = true;
                            
                            // 使用window.location方式触发文件下载
                            window.location.href = '/docs/download-zip?path=' + encodeURIComponent(finalPath);
                            
                            // 恢复按钮状态
                            setTimeout(() => {
                                this.innerHTML = '<i class="fas fa-download mr-2"></i> 下载压缩包';
                                this.disabled = false;
                                try {
                                    showNotification('文档压缩包已开始下载', 'success');
                                } catch (e) {
                                    alert('文档压缩包已开始下载');
                                }
                            }, 2000);
                        } else {
                            try {
                                showNotification('没有找到可下载的文档路径', 'error');
                            } catch (e) {
                                alert('没有找到可下载的文档路径');
                            }
                        }
                    });

                    // 复制路径按钮的事件绑定已移到setupButtonEvents函数中
                    // 如果直接在这里定义会导致"copyPathBtn is not defined"错误

                    // 搜索框输入事件
                    searchInput.addEventListener('input', filterRequirements);

                    // 排序选择变化事件
                    sortBySelect.addEventListener('change', filterRequirements);

                    // 文件拖放功能
                    const dropZone = document.querySelector('.border-dashed');

                    ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
                        dropZone.addEventListener(eventName, preventDefaults, false);
                    });

                    ['dragenter', 'dragover'].forEach(eventName => {
                        dropZone.addEventListener(eventName, highlight, false);
                    });

                    ['dragleave', 'drop'].forEach(eventName => {
                        dropZone.addEventListener(eventName, unhighlight, false);
                    });

                    // 处理文件拖放
                    dropZone.addEventListener('drop', handleDrop, false);

                    // 轮询任务状态
                    function pollTaskStatus(taskId, onProgress, onComplete, onError) {
                        const MAX_RETRIES = 150;  // 最多轮询150次（大约5分钟）
                        const POLL_INTERVAL = 2000;  // 2秒轮询一次
                        let retryCount = 0;
                        
                        function checkStatus() {
                            axios.get(`/tasks/${taskId}`)
                                .then(response => {
                                    if (response.data.success) {
                                        const taskData = response.data.data;
                                        
                                        // 更新进度条
                                        if (taskData.progress !== undefined) {
                                            document.getElementById('taskProgressBar').style.width = `${taskData.progress}%`;
                                            document.getElementById('taskProgressText').textContent = `${taskData.progress}%`;
                                        }
                                        
                                        // 更新状态
                                        if (taskData.status) {
                                            let statusHtml = '';
                                            let statusClass = '';
                                            let statusIcon = '';
                                            let statusText = '';
                                            
                                            switch (taskData.status) {
                                                case 'PENDING':
                                                    statusClass = 'bg-yellow-100 text-yellow-800';
                                                    statusIcon = 'fa-clock';
                                                    statusText = '等待中';
                                                    break;
                                                case 'PROCESSING':
                                                    statusClass = 'bg-blue-100 text-blue-800';
                                                    statusIcon = 'fa-spinner fa-spin';
                                                    statusText = '处理中';
                                                    break;
                                                case 'COMPLETED':
                                                    statusClass = 'bg-green-100 text-green-800';
                                                    statusIcon = 'fa-check';
                                                    statusText = '已完成';
                                                    break;
                                                case 'FAILED':
                                                    statusClass = 'bg-red-100 text-red-800';
                                                    statusIcon = 'fa-exclamation-triangle';
                                                    statusText = '失败';
                                                    break;
                                                default:
                                                    statusClass = 'bg-gray-100 text-gray-800';
                                                    statusIcon = 'fa-question';
                                                    statusText = '未知';
                                            }
                                            
                                            statusHtml = `<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full ${statusClass}">
                                                <i class="fas ${statusIcon} mr-1"></i> ${statusText}
                                            </span>`;
                                            
                                            document.getElementById('taskStatus').innerHTML = statusHtml;
                                        }
                                        
                                        // 如果错误信息中包含"刷新中"，这是一个临时状态，继续轮询
                                        if (taskData.errorMessage && taskData.errorMessage.includes("刷新中")) {
                                            console.log(`任务${taskId}状态刷新中，等待重试...`);
                                            setTimeout(checkStatus, POLL_INTERVAL);
                                            return;
                                        }
                                        
                                        // 如果任务已完成或失败，停止轮询
                                        if (taskData.status === 'COMPLETED' || taskData.status === 'FAILED') {
                                            console.log(`任务${taskId}已${taskData.status === 'COMPLETED' ? '完成' : '失败'}，停止轮询`);
                                            
                                            // 如果任务已完成，启用下载按钮
                                            if (taskData.status === 'COMPLETED' && taskData.outputDir) {
                                                downloadZipBtn.disabled = false;
                                                downloadZipBtn.classList.remove('opacity-50', 'cursor-not-allowed');
                                                downloadZipBtn.setAttribute('data-path', taskData.outputDir);
                                            }
                                            
                                            // 如果任务失败，显示错误信息
                                            if (taskData.status === 'FAILED' && taskData.errorMessage) {
                                                showNotification(`任务执行失败: ${taskData.errorMessage}`, 'error');
                                            }
                                            
                                            return;
                                        }
                                        
                                        // 继续轮询
                                        setTimeout(checkStatus, POLL_INTERVAL);
                                    } else {
                                        console.error('获取任务状态失败:', response.data.message);
                                        
                                        // 即使失败也不显示错误给用户，而是静默重试
                                        if (retryCount < MAX_RETRIES) {
                                            console.log(`获取任务状态失败，${POLL_INTERVAL / 1000}秒后重试...`);
                                            setTimeout(checkStatus, POLL_INTERVAL);
                                        } else {
                                            console.error(`获取任务状态失败次数过多，停止轮询`);
                                        }
                                    }
                                })
                                .catch(error => {
                                    console.error('轮询任务状态出错:', error);
                                    
                                    // 出错后继续轮询，但间隔时间更长
                                    const retryInterval = pollingInterval * 2;
                                    console.log(`网络错误，${retryInterval / 1000}秒后重试...`);
                                    setTimeout(checkStatus, retryInterval);
                                });
                        }
                        
                        // 开始轮询
                        checkStatus();
                    }

                    // 为确保按钮事件绑定成功，在DOM加载完成后再次绑定事件
                    function setupButtonEvents() {
                        console.log("重新设置按钮事件...");
                        
                        // 下载文档压缩包事件
                        const downloadZipBtn = document.getElementById('downloadZipBtn');
                        if (downloadZipBtn) {
                            console.log("找到下载按钮，绑定事件");
                            downloadZipBtn.onclick = function() {
                                // 优先从按钮的data-path属性获取路径
                                const path = this.getAttribute('data-path');
                                // 如果没有，才尝试从输出路径元素获取
                                const outputPathEl = document.getElementById('outputPath');
                                const outputPath = outputPathEl ? outputPathEl.textContent : null;
                                
                                const finalPath = path || outputPath;
                                
                                if (finalPath) {
                                    // 显示下载中提示
                                    this.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> 打包下载中...';
                                    this.disabled = true;
                                    
                                    // 使用window.location方式触发文件下载
                                    window.location.href = '/docs/download-zip?path=' + encodeURIComponent(finalPath);
                                    
                                    // 恢复按钮状态
                                    setTimeout(() => {
                                        this.innerHTML = '<i class="fas fa-download mr-2"></i> 下载压缩包';
                                        this.disabled = false;
                                        try {
                                            showNotification('文档压缩包已开始下载', 'success');
                                        } catch (e) {
                                            alert('文档压缩包已开始下载');
                                        }
                                    }, 2000);
                                } else {
                                    try {
                                        showNotification('没有找到可下载的文档路径', 'error');
                                    } catch (e) {
                                        alert('没有找到可下载的文档路径');
                                    }
                                }
                            };
                        }
                        

                        
                        // 复制路径按钮事件
                        const copyPathBtn = document.getElementById('copyPathBtn');
                        if (copyPathBtn) {
                            console.log("找到复制路径按钮，绑定事件");
                            copyPathBtn.onclick = function() {
                                const path = document.getElementById('outputPath').textContent;
                                if (path) {
                                    try {
                                        copyToClipboard(path);
                                    } catch (e) {
                                        // 备用复制方法
                                        const textarea = document.createElement('textarea');
                                        textarea.value = path;
                                        document.body.appendChild(textarea);
                                        textarea.select();
                                        document.execCommand('copy');
                                        document.body.removeChild(textarea);
                                        
                                        // 显示复制成功提示
                                        this.innerHTML = '<i class="fas fa-check"></i>';
                                        setTimeout(() => {
                                            this.innerHTML = '<i class="fas fa-copy"></i>';
                                            alert('路径已复制到剪贴板');
                                        }, 2000);
                                    }
                                }
                            };
                        }
                    }
                    
                    // 等待页面完全加载后设置事件
                    window.addEventListener('load', setupButtonEvents);
                    
                    // 立即尝试设置一次
                    setupButtonEvents();
                    
                    // 在步骤切换到第3步时，确保按钮事件已绑定
                    const originalShowStep = window.showStep || showStep;
                    window.showStep = function(stepNumber) {
                        // 调用原始函数
                        originalShowStep(stepNumber);
                        
                        // 如果切换到第3步，确保按钮事件已绑定
                        if (stepNumber === 3) {
                            setTimeout(setupButtonEvents, 100);
                        }
                    };

                    // 更新任务信息
                    function updateTaskInfo(taskId) {
                        // 设置任务ID显示
                        document.getElementById('taskProgress').classList.remove('hidden');
                        document.getElementById('taskProgressBar').style.width = '10%';
                        document.getElementById('taskProgressText').textContent = '10%';
                        document.getElementById('taskStatus').innerHTML = '<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-blue-100 text-blue-800"><i class="fas fa-spinner fa-spin mr-1"></i> 处理中</span>';
                        
                        // 禁用下载按钮
                        downloadZipBtn.disabled = true;
                        downloadZipBtn.classList.add('opacity-50', 'cursor-not-allowed');
                    }
                    
                    // 开始轮询任务状态
                    function startTaskPolling(taskId) {
                        // 初始轮询间隔 (2秒)
                        let pollingInterval = 2000;
                        // 最大轮询间隔 (10秒)
                        const maxPollingInterval = 10000;
                        // 轮询计数
                        let pollingCount = 0;
                        // 最大轮询次数，防止无限轮询 (30分钟，最多180次)
                        const maxPollingCount = 180;
                        
                        // 轮询函数
                        function pollTaskStatus() {
                            pollingCount++;
                            
                            // 如果已经超过最大轮询次数，停止轮询
                            if (pollingCount > maxPollingCount) {
                                console.log(`已超过最大轮询次数(${maxPollingCount})，停止轮询`);
                                return;
                            }
                            
                            axios.get(`/tasks/${taskId}`)
                                .then(response => {
                                    if (response.data.success) {
                                        const taskData = response.data.data;
                                        
                                        // 更新进度条
                                        if (taskData.progress !== undefined) {
                                            document.getElementById('taskProgressBar').style.width = `${taskData.progress}%`;
                                            document.getElementById('taskProgressText').textContent = `${taskData.progress}%`;
                                        }
                                        
                                        // 更新状态
                                        if (taskData.status) {
                                            let statusHtml = '';
                                            let statusClass = '';
                                            let statusIcon = '';
                                            let statusText = '';
                                            
                                            switch (taskData.status) {
                                                case 'PENDING':
                                                    statusClass = 'bg-yellow-100 text-yellow-800';
                                                    statusIcon = 'fa-clock';
                                                    statusText = '等待中';
                                                    break;
                                                case 'PROCESSING':
                                                    statusClass = 'bg-blue-100 text-blue-800';
                                                    statusIcon = 'fa-spinner fa-spin';
                                                    statusText = '处理中';
                                                    break;
                                                case 'COMPLETED':
                                                    statusClass = 'bg-green-100 text-green-800';
                                                    statusIcon = 'fa-check';
                                                    statusText = '已完成';
                                                    break;
                                                case 'FAILED':
                                                    statusClass = 'bg-red-100 text-red-800';
                                                    statusIcon = 'fa-exclamation-triangle';
                                                    statusText = '失败';
                                                    break;
                                                default:
                                                    statusClass = 'bg-gray-100 text-gray-800';
                                                    statusIcon = 'fa-question';
                                                    statusText = '未知';
                                            }
                                            
                                            statusHtml = `<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full ${statusClass}">
                                                <i class="fas ${statusIcon} mr-1"></i> ${statusText}
                                            </span>`;
                                            
                                            document.getElementById('taskStatus').innerHTML = statusHtml;
                                        }
                                        
                                        // 如果错误信息中包含"刷新中"，这是一个临时状态，继续轮询
                                        if (taskData.errorMessage && taskData.errorMessage.includes("刷新中")) {
                                            console.log(`任务${taskId}状态刷新中，等待重试...`);
                                            setTimeout(pollTaskStatus, pollingInterval);
                                            return;
                                        }
                                        
                                        // 如果任务已完成或失败，停止轮询
                                        if (taskData.status === 'COMPLETED' || taskData.status === 'FAILED') {
                                            console.log(`任务${taskId}已${taskData.status === 'COMPLETED' ? '完成' : '失败'}，停止轮询`);
                                            
                                            // 如果任务已完成，启用下载按钮
                                            if (taskData.status === 'COMPLETED' && taskData.outputDir) {
                                                downloadZipBtn.disabled = false;
                                                downloadZipBtn.classList.remove('opacity-50', 'cursor-not-allowed');
                                                downloadZipBtn.setAttribute('data-path', taskData.outputDir);
                                            }
                                            
                                            // 如果任务失败，显示错误信息
                                            if (taskData.status === 'FAILED' && taskData.errorMessage) {
                                                showNotification(`任务执行失败: ${taskData.errorMessage}`, 'error');
                                            }
                                            
                                            return;
                                        }
                                        
                                        // 继续轮询
                                        setTimeout(pollTaskStatus, pollingInterval);
                                        
                                        // 增加轮询间隔，最多增加到最大间隔
                                        pollingInterval = Math.min(pollingInterval * 1.2, maxPollingInterval);
                                    } else {
                                        console.error('获取任务状态失败:', response.data.message);
                                        
                                        // 即使失败也不显示错误给用户，而是静默重试
                                        if (pollingCount < maxPollingCount) {
                                            console.log(`获取任务状态失败，${pollingInterval / 1000}秒后重试...`);
                                            setTimeout(pollTaskStatus, pollingInterval);
                                        } else {
                                            console.error(`获取任务状态失败次数过多，停止轮询`);
                                        }
                                    }
                                })
                                .catch(error => {
                                    console.error('轮询任务状态出错:', error);
                                    
                                    // 出错后继续轮询，但间隔时间更长
                                    const retryInterval = pollingInterval * 2;
                                    console.log(`网络错误，${retryInterval / 1000}秒后重试...`);
                                    setTimeout(pollTaskStatus, retryInterval);
                                });
                        }
                        
                        // 开始轮询
                        pollTaskStatus();
                    }
                }
            )
            ;    </script>
    </body>
</html> 